Jvm如何内存调优? 您所在的位置:网站首页 jvm 占用内存 Jvm如何内存调优?

Jvm如何内存调优?

#Jvm如何内存调优?| 来源: 网络整理| 查看: 265

身为一个Java开发人员,想必对Jvm都不陌生,Java程序跑在Jvm中,但是Jvm是如何让我们的程序跑的高效的呢?我们又该如何去做内存调优呢,今天一起来和大家探讨下。

Jvm内存结构1、JVM 究竟需不需要调优?

JVM 经过这么多年的发展和验证,整体是非常健壮的。个人认为99%的情况下,基本用不到 JVM 调优。通常来说,我们的 JVM 参数配置大多还是会遵循 JVM 官方的建议,例如:

-XX:NewRatio=2,年轻代:老年代=1:2

-XX:SurvivorRatio=8,eden:survivor=8:1

堆内存设置为物理内存的3/4左右

等等

JVM 参数的默认(推荐)值都是经过 JVM 团队的反复测试和前人的充分验证得出的比较合理的值,因此通常来说是比较靠谱和通用的,一般不会出大问题。

当然,更重要的是,大部分的应用 QPS 都不到10,数据量不到几万,这种低压环境下,想让 JVM 出问题,说实话也挺难的。

那么还需要内存调优吗?

俗话说得好,凡事无绝对,还是有一小部分场景,是可能需要用到 JVM 调优的。具体哪些场景,我们在下面介绍。

值得一提的是,我们这边所说的 JVM 调优更多的是针对自己的业务场景对 JVM 参数进行优化调整,使其更适合我们的业务,而不是指对 JVM 源码的改动。

Jvm何时优化?

忌过早优化。《计算机程序设计艺术》的作者高德纳(Donald Ervin Knuth)曾说过一句经典的话:

The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming.

真正的问题是,程序猿在错误的地方和错误的时间花了太多的时间担心效率问题;过早的优化是编程中所有(或者至少是大部分)罪恶的根源。

忌过早并不是说就完全不管,比较正确的做法应该是给核心服务的一些重要 JVM 指标配上监控告警,当指标出现波动或者异常时,能及时介入排查。

Jvm优化步骤

分析和定位当前系统的瓶颈

对于JVM的核心指标,我们的关注点和常用工具如下:

1)CPU指标

查看占用CPU最多的进程

查看占用CPU最多的线程

查看线程堆栈快照信息

分析代码执行热点

查看哪个代码占用CPU执行时间最长

查看每个方法占用CPU时间比例

常见的命令:

// 显示系统各个进程的资源使用情况 top // 查看某个进程中的线程占用情况 top -Hp pid // 查看当前 Java 进程的线程堆栈信息 jstack pid

常见的工具:JProfiler、JVM Profiler、Arthas等。

2)JVM 内存指标

查看当前 JVM 堆内存参数配置是否合理

查看堆中对象的统计信息

查看堆存储快照,分析内存的占用情况

查看堆各区域的内存增长是否正常

查看是哪个区域导致的GC

查看GC后能否正常回收到内存

常见的命令:

// 查看当前的 JVM 参数配置 ps -ef | grep java // 查看 Java 进程的配置信息,包括系统属性和JVM命令行标志 jinfo pid // 输出 Java 进程当前的 gc 情况 jstat -gc pid // 输出 Java 堆详细信息 jmap -heap pid // 显示堆中对象的统计信息 jmap -histo:live pid // 生成 Java 堆存储快照dump文件 jmap -F -dump:format=b,file=dumpFile.phrof pid

常见的工具:Eclipse MAT、JConsole等。

3)JVM GC指标

查看每分钟GC时间是否正常

查看每分钟YGC次数是否正常

查看FGC次数是否正常

查看单次FGC时间是否正常

查看单次GC各阶段详细耗时,找到耗时严重的阶段

查看对象的动态晋升年龄是否正常

JVM 的 GC指标一般是从 GC 日志里面查看,默认的 GC 日志可能比较少,我们可以添加以下参数,来丰富我们的GC日志输出,方便我们定位问题。

GC日志常用 JVM 参数:

// 打印GC的详细信息 -XX:+PrintGCDetails // 打印GC的时间戳 -XX:+PrintGCDateStamps // 在GC前后打印堆信息 -XX:+PrintHeapAtGC // 打印Survivor区中各个年龄段的对象的分布信息 -XX:+PrintTenuringDistribution // JVM启动时输出所有参数值,方便查看参数是否被覆盖 -XX:+PrintFlagsFinal // 打印GC时应用程序的停止时间 -XX:+PrintGCApplicationStoppedTime // 打印在GC期间处理引用对象的时间(仅在PrintGCDetails时启用) -XX:+PrintReferenceGC

以上就是我们定位系统瓶颈的常用手段,大部分问题通过以上方式都能定位出问题原因,然后结合代码去找到问题根源。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有